package com.xmmj.baselibrary.base.activity.base

import android.annotation.SuppressLint
import android.content.res.Resources
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.*
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.xmmj.baselibrary.R
import com.xmmj.baselibrary.base.activity.lib.LibBaseActivity
import com.xmmj.baselibrary.base.activity.mvvm.IBaseView
import com.xmmj.baselibrary.widget.loading.LoadingDialog
import com.xmmj.baselibrary.utils.SP

/**
 * 实现公共UI的Activity:
 * 1.公共的标题栏
 * 2.支持沉浸式
 * 3.显示/隐藏Loading
 * 4.显示/隐藏错误提示
 * 。。。。。。
 */
abstract class BaseActivity : LibBaseActivity(), IBaseView {
    private lateinit var baseRoot: View

    private lateinit var vBaseStateBarAndTitleBar: View

    private lateinit var vBaseStateBar: View

    private lateinit var tvBaseTitle: TextView

    private lateinit var tvBaseRight: TextView

    private lateinit var llBaseRoot: LinearLayout

    private lateinit var rlBaseTitleBar: RelativeLayout

    private lateinit var rlBaseError: RelativeLayout

    private lateinit var tvBaseError: TextView

    private lateinit var btnBaseError: Button

    private lateinit var mvvmView: View

    private var mDialog: LoadingDialog? = null

    companion object {
        //字体缩放比例
        const val FONT_SCALE = "font_scale"
    }

    @SuppressLint("InflateParams")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //1.先从根布局中取出mvvm的布局
        val decorView: View = window.decorView
        val contentView: ViewGroup = decorView.findViewById(android.R.id.content)
        mvvmView = contentView.getChildAt(0)

        //2.然后清空根布局
        contentView.removeAllViews()

        //3.接着添加公共布局
        baseRoot = layoutInflater.inflate(R.layout.activity_base, null)
        contentView.addView(baseRoot)

        //整个页面背景部分
        llBaseRoot = baseRoot.findViewById(R.id.ll_base_root)
        llBaseRoot.setBackgroundResource(setBackground())

        //状态栏和标题栏公共背景
        vBaseStateBarAndTitleBar = baseRoot.findViewById(R.id.v_base_state_bar_and_title_bar)
        vBaseStateBarAndTitleBar.setBackgroundResource(setStateBarAndTitleBarBackground())

        //状态栏部分
        vBaseStateBar = baseRoot.findViewById(R.id.v_base_state_bar)
        val params = vBaseStateBar.layoutParams as RelativeLayout.LayoutParams
        params.height = if (isImmersion()) 0 else statusBarHeight
        vBaseStateBar.setBackgroundResource(setStatusBarResource())

        //标题栏部分
        rlBaseTitleBar = baseRoot.findViewById(R.id.rl_base_title_bar)
        rlBaseTitleBar.visibility = if (setTitleBarVisible()) View.VISIBLE else View.GONE
        rlBaseTitleBar.setBackgroundResource(setTitleBarColor())
        val ivBaseLeft: ImageView = baseRoot.findViewById(R.id.iv_base_left)
        tvBaseTitle = baseRoot.findViewById(R.id.tv_base_title)
        tvBaseRight = baseRoot.findViewById(R.id.tv_base_right)
        val rlBaseLeft: RelativeLayout = baseRoot.findViewById(R.id.rl_base_left)
        tvBaseTitle.visibility = if (setTitleVisible()) View.VISIBLE else View.GONE
        tvBaseTitle.text = setTitle()
        tvBaseTitle.setTextColor(resources.getColor(setTitleTxtColor()))
        rlBaseLeft.setOnClickListener { onLeftBtnClick() }
        ivBaseLeft.visibility = if (setLeftBtnVisible()) View.VISIBLE else View.GONE
        ivBaseLeft.setBackgroundResource(setLeftBtnDrawable())
        tvBaseRight.visibility = if (setRightBtnVisible()) View.VISIBLE else View.GONE
        tvBaseRight.text = setRightBtnText()
        tvBaseRight.setTextColor(resources.getColor(setRightTextColor()))
        tvBaseRight.setCompoundDrawablesWithIntrinsicBounds(setRightBtnDrawable(), 0, 0, 0)
        tvBaseRight.setOnClickListener { onRightBtnClick() }

        //body部分
        val rlBaseBody: RelativeLayout = baseRoot.findViewById(R.id.rl_base_body)

        //错误提示部分
        rlBaseError = baseRoot.findViewById(R.id.rl_base_error)
        rlBaseError.visibility = View.GONE
        tvBaseError = baseRoot.findViewById(R.id.tv_base_error)
        btnBaseError = baseRoot.findViewById(R.id.btn_base_error)
        btnBaseError.setOnClickListener { onRequest() }

        //4.最后添加Mvvm布局
        rlBaseBody.addView(
            mvvmView,
            RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
            )
        )

        //发起请求
        onRequest()
    }

    /**
     * 是否支持沉浸式
     *
     *
     * 需要支持如下样式
     * <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     * <item name="colorPrimary">@color/color_transparent</item>
     * <item name="colorPrimaryDark">@color/color_transparent</item>
     * <item name="colorAccent">@color/color_transparent</item>
     * <item name="android:clipToPadding">true</item>
     * <item name="android:windowBackground">@color/color_transparent</item>
     * </style>
     */
    open fun isImmersion(): Boolean {
        return false
    }

    /**
     * 动态设置是否沉浸
     *
     * @param isImmersion 沉浸式
     */
    open fun setImmersion(isImmersion: Boolean) {
        vBaseStateBar.layoutParams.height = if (isImmersion) 0 else statusBarHeight
        (rlBaseTitleBar.layoutParams as RelativeLayout.LayoutParams).topMargin =
            if (isImmersion()) statusBarHeight else 0
    }

    /**
     * 设置标题栏是否可见
     */
    open fun setTitleBarVisible(): Boolean {
        return false
    }

    /**
     * 获取标题栏
     */
    val titleBar: View
        get() = rlBaseTitleBar

    /**
     * 设置标题栏背景色
     */
    open fun setTitleBarColor(): Int {
        return R.color.color_transparent
    }

    /**
     * 设置标题栏是否可见
     */
    open fun setTitleVisible(): Boolean {
        return true
    }

    /**
     * 设置标题文案
     */
    open fun setTitle(): String {
        return ""
    }

    /**
     * 设置标题的字体颜色
     */
    open fun setTitleTxtColor(): Int {
        return R.color.color_171717
    }

    /**
     * 设置左边按钮是否可见
     */
    open fun setLeftBtnVisible(): Boolean {
        return true
    }

    /**
     * 设置左边按钮的图标
     */
    open fun setLeftBtnDrawable(): Int {
        return R.drawable.ic_apply_back
    }

    /**
     * 设置右边按钮是否可见
     */
    open fun setRightBtnVisible(): Boolean {
        return false
    }

    /**
     * 设置右边按钮的文案
     */
    open fun setRightBtnText(): String {
        return ""
    }

    /**
     * 设置右边按钮的字体颜色
     */
    open fun setRightTextColor(): Int {
        return R.color.color_171717
    }

    /**
     * 设置右边按钮的图标
     */
    open fun setRightBtnDrawable(): Int {
        return 0
    }

    /**
     * 左边按钮的点击事件
     */
    open fun onLeftBtnClick() {
        finish()
    }

    /**
     * 右边按钮的点击事件
     */
    open fun onRightBtnClick() {}

    /**
     * 设置状态栏颜色
     */
    override fun setStatusBarResource(): Int {
        return R.color.color_transparent
    }

    /**
     * 设置整个页面的背景色
     */
    open fun setBackground(): Int {
        return R.color.color_transparent
    }

    /**
     * 设置状态栏是否为高亮模式（文字和图标为黑色，背景为透明）
     */
    override fun isStatusBarLightMode(): Boolean {
        return super.isStatusBarLightMode()
    }

    /**
     * 动态设置页面背景
     *
     * @param color 颜色
     */
    open fun setBackground(color: Int) {
        llBaseRoot.setBackgroundResource(color)
    }

    /**
     * 设置状态栏和标题栏公共背景
     */
    open fun setStateBarAndTitleBarBackground(): Int {
        return R.color.color_transparent
    }

    /**
     * 动态设置状态栏和标题栏公共背景
     */
    open fun setStateBarAndTitleBarBackground(resId: Int) {
        vBaseStateBarAndTitleBar.setBackgroundResource(resId)
    }

    /**
     * 动态设置标题文案
     *
     * @param title 标题
     */
    open fun setTitle(title: String?) {
        tvBaseTitle.text = title
    }

    /**
     * 动态设置标题字体大小
     *
     * @param textSize 字体大小
     */
    open fun setTitleSize(textSize: Float) {
        tvBaseTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
    }

    /**
     * 获取右边按钮控件
     */
    open val rightBtn: TextView?
        get() = tvBaseRight

    /**
     * 显示加载对话框
     *
     * @param cancelable 是否可以触摸取消
     */
    override fun showLoading(cancelable: Boolean) {
        hideLoading()
        if (mDialog == null) {
            mDialog = LoadingDialog()
        }
        mDialog!!.isCancelable = cancelable
        mDialog!!.show(this)
    }

    /**
     * 隐藏加载对话框
     */
    override fun hideLoading() {
        mDialog?.dismiss()
        mDialog = null
    }

    /**
     * 重新登录
     */
    override fun onReLogin() {

    }

    /**
     * 发起请求
     */
    override fun onRequest() {
        rlBaseError.visibility = View.GONE
    }

    /**
     * 吐司
     *
     * @param msg 文案
     */
    override fun toast(msg: String?) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
    }

    /**
     * 显示页面错误提示
     *
     * @param imageId   图片
     * @param errorText 错误文案
     * @param btnText   按钮文案
     */
    override fun showError(imageId: Int, errorText: String?, btnText: String?) {
        rlBaseError.visibility = View.VISIBLE
        tvBaseError.visibility = View.VISIBLE
        btnBaseError.visibility = View.VISIBLE
        tvBaseError.setCompoundDrawablesWithIntrinsicBounds(0, imageId, 0, 0)
        tvBaseError.text = errorText
        btnBaseError.text = btnText
    }

    /**
     * 显示空提示
     *
     * @param isShow   是否显示
     * @param imageId  图片
     * @param hintText 提示文案
     */
    override fun showEmpty(isShow: Boolean, imageId: Int, hintText: String?) {
        rlBaseError.visibility = if (isShow) View.VISIBLE else View.GONE
        tvBaseError.visibility = if (isShow) View.VISIBLE else View.GONE
        btnBaseError.visibility = View.GONE
        tvBaseError.setCompoundDrawablesWithIntrinsicBounds(0, imageId, 0, 0)
        tvBaseError.text = hintText
    }

    /**
     * 结束刷新
     */
    override fun finishRefresh() {
        val refresh = findView(mvvmView, SmartRefreshLayout::class.java)
        refresh?.finishRefresh()
    }

    /**
     * 结束加载更多
     *
     * @param noMoreData
     */
    override fun finishLoadMore(noMoreData: Boolean) {
        val refresh = findView(mvvmView, SmartRefreshLayout::class.java)
        if (noMoreData) {
            refresh?.finishLoadMoreWithNoMoreData()
        } else {
            refresh?.setNoMoreData(false)
            refresh?.finishLoadMore()
        }
    }

    /**
     * 找到指定类型的控件
     */
    private fun <T : View?> findView(view: View, cls: Class<T>): T? {
        if (view.javaClass == cls) {
            return view as T
        }
        if (view is ViewGroup) {
            for (index in 0..view.childCount) {
                if (view.getChildAt(index) != null) {
                    if (findView(view.getChildAt(index), cls) != null) {
                        return findView(view.getChildAt(index), cls)
                    }
                }
            }
        }
        return null
    }

    /**
     * 重新该方法，控制APP加载的字体大小
     */
    override fun getResources(): Resources {
        val res = super.getResources()
        val config = res.configuration
        val fontScale: Float = SP(this).getFloat(FONT_SCALE)
        config.fontScale = if (fontScale <= 0) 1F else fontScale
        res.updateConfiguration(config, res.displayMetrics)
        return res
    }
}